package com.mm.base.aop;

import com.mm.serivce.common.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;

/**
 * 描述: WeChat接口幂等性-放置重复提交(aop)
 *
 * @author: yanglin
 * @Date: 2021-09-03-8:25
 * @Version: 1.0
 */
@Slf4j
@Aspect
@Order(value = 2)
@Component
public class IdempotentAop {

    private final TokenService tokenService;

    public IdempotentAop(TokenService tokenService) {
        this.tokenService = tokenService;
    }

    /**
     * 按包路径进行拦截
     */
    @Pointcut("execution(* com.mm.controller.mp.*.*(..) )")
    public void idempotent() {
    }

    /**
     * 方法执行前
     *
     * @param joinPoint
     * @throws Throwable
     */
    @Before("idempotent()")
    public void before(JoinPoint joinPoint) throws Throwable {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 从获取RequestAttributes中获取HttpServletRequest的信息
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        String url = request.getRequestURL().toString();
        // 幂等性校验, 校验通过则放行, 校验失败则抛出异常, 并通过统一异常处理返回友好提示
        log.info("请求[{}];验证Token;", url);
        tokenService.checkToken(request);
    }

    /**
     * 环绕通知
     *
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around("idempotent()")
    public Object idempotentFilter(ProceedingJoinPoint pjp) throws Throwable {
        return pjp.proceed();
    }

    /**
     * 方法执行后
     *
     * @param point
     */
    @After("idempotent()")
    public void after(JoinPoint point) {

    }

}
